package com.cium.aqie.highOrderFunction

/**
 * @Function: 函数复合
 * @Author: aqie
 * @Date: 2019/9/2 8:33
 */

//f(g(x))   m(x) = f(g(x))
val add5 = {i: Int -> i + 5}         // g(x)
val multiplyBy2 = {i : Int -> i * 2} // f(x)
val add5AndMultiplyBy2 = add5 andThen multiplyBy2
val add5ComposeMultiplyBy2 = add5 compose  multiplyBy2

/**
 * 定义复合函数方法
 * P1 P2 : 表示参数值,分别表示(参数类型, 返回值类型)
 * andThen 是 Function1 的扩展方法
 * infix 中缀表达式 调用函数不用.也不用括号
 *
 */
infix fun <P1, P2, R> Function1<P1, P2>.andThen(function: Function1<P2, R>): Function1<P1,R>{
    return fun(p1: P1): R{
        return function.invoke(this.invoke(p1))
    }
}

// 运算顺序不一样
infix fun <P1,P2, R> Function1<P2, R>.compose(function: Function1<P1, P2>): Function1<P1, R>{
    return fun(p1: P1): R{
        return this.invoke(function.invoke(p1))
    }
}
fun main() {
    println(multiplyBy2(add5(1)))   // 12  (1 + 5) * 2
    println(add5AndMultiplyBy2(1))  // 12
    println(add5ComposeMultiplyBy2(1))     // 7  (1*2 + 5)
}